import time

from celery import shared_task

from Problems.models import ProblemTag
from Robots.Exceptions import *
from Robots.RobotFactory import RobotFactory
from Submission.config import Verdict
from Submission.models import Submission


@shared_task(name='show_all_problems')
def show_all_problems():
    from Problems.models import Problem
    problems = Problem.objects.all()
    for problem in problems:
        print(problem)


@shared_task(name='submit_code_to_remote_robot')
def submit_code_to_remote_robot(submit_data, problem_data):
    available_robot = RobotFactory.create_robot(problem_data["remote_oj"]["name"], get_problem=False)
    try:
        remote_id = available_robot.submit(
            language=submit_data["lang"],
            code=submit_data["code"],
            origin_id=problem_data["remote_id"]
        )
        print(remote_id)
        submission = Submission.objects.get(id=submit_data["submission_id"])
        submission.remote_id = remote_id
        submission.save()
    except SubmitProblemFailed as e:
        submission = Submission.objects.get(id=submit_data["submission_id"])
        submission.remote_verdict = "Submit Failed"
        submission.additional_info = str(e)
        submission.save()
        return {"status": "fail", "message": "提交失败" + str(e), "submission_id": None}
    except Exception as e:
        print(e)
        time.sleep(2)
        available_robot.release()
        return submit_code_to_remote_robot(submit_data, problem_data)
    finally:
        available_robot.release()
    return {"status": "success", "message": "提交成功", "submission_id": remote_id}


@shared_task(name='get_submission_result')
def get_submission_result(submission_id, remote_id=None):
    submission = Submission.objects.get(id=submission_id)
    if submission.remote_verdict == "Submit Failed":
        return
    robot = RobotFactory.create_robot(submission.problem.remote_oj.name, get_problem=True)
    data = robot.get_result(submission_id=submission.remote_id, username=submission.user.username, contestId=remote_id)
    submission.remote_verdict = data["remote_verdict"]
    submission.time_cost = data["time_cost"]
    submission.memory_cost = data["memory_cost"]
    remote_verdict = data["remote_verdict"]
    if "Accepted" in remote_verdict:
        submission.verdict = Verdict.ACCEPTED
    elif "Wrong" in remote_verdict:
        submission.verdict = Verdict.WRONG_ANSWER
    elif "Compilation" in remote_verdict:
        submission.verdict = Verdict.COMPILE_ERROR
    elif "Runtime" in remote_verdict:
        submission.verdict = Verdict.RUNTIME_ERROR
    elif "Time" in remote_verdict:
        submission.verdict = Verdict.TIME_LIMIT_EXCEEDED
    elif "Memory" in remote_verdict:
        submission.verdict = Verdict.MEMORY_LIMIT_EXCEEDED
    else:
        submission.verdict = Verdict.PENDING
    submission.save()
    if submission.verdict == Verdict.PENDING:
        time.sleep(2)
        get_submission_result(submission_id, remote_id)





@shared_task
def analyze_submission(submission_id, code):
    import json

    import requests

    API_KEY = "Ytvw0hkvjPaU9F8IgEyWSytz"
    SECRET_KEY = "rJgItexEUoS60xglPCO0VzAuXNBI3SSk"

    def get_access_token():
        """
        使用 AK，SK 生成鉴权签名（Access Token）
        :return: access_token，或是None(如果错误)
        """
        url = "https://aip.baidubce.com/oauth/2.0/token"
        params = {"grant_type": "client_credentials", "client_id": API_KEY, "client_secret": SECRET_KEY}
        return str(requests.post(url, params=params).json().get("access_token"))

    def get_result(text):
        url = "https://aip.baidubce.com/rpc/2.0/ai_custom/v1/wenxinworkshop/chat/completions_pro?access_token=" + get_access_token()

        payload = json.dumps({
            "messages": [
                {
                    "role": "user",
                    "content": text,
                }
            ],
            "temperature": 0.95,
            "top_p": 0.8,
            "penalty_score": 1,
            "system": "你是由上海理工大学科创工坊社团研发的人工智能语言模型。你的工作就是我给你一段 C++ 或者 Python ，或者 JAVA 的代码，然后你对代码进行识别。代码识别只需要判断这份代码使用的算法是否是['greedy', 'math', 'constructive algorithms', 'brute force', 'sortings', 'dp', 'data structures', 'binary search', 'strings', 'number theory', 'two pointers', 'graphs', 'dfs and similar', 'combinatorics', 'Number Theory', 'bitmasks', 'divide and conquer', 'dsu', 'Segment Tree', 'Fenwick', 'SPFA', 'Floyd', 'Dijkstra', 'Dicnic', 'Edmonds Karp', 'Exgcd', 'Euler', 'Suffix Array', 'KMP', 'Hash', 'Manacher', 'DFS', 'BFS', 'Stack', 'Queue', 'PriorityQueue', 'ST Table', '2-SAT', 'Matrix Power', 'LCA', 'Prefix Sum'] 中的一种或多种。你只需要回答列表中出现的算法，用逗号隔开，并和列表对应算法的大小写完全一致。除了告诉我列表中出现的算法名称，如果你没有识别出任何算法，回复我 'None'。不要提供任何解释，不要用任何东西来回应，不要提供任何解释，不要用任何东西来回应，不要提供任何解释，不要用任何东西来回应。",
            "disable_search": False,
            "enable_citation": False
        })
        headers = {
            'Content-Type': 'application/json'
        }

        response = requests.request("POST", url, headers=headers, data=payload)

        return response.text

    # 先去掉 code 中的空格
    code = code.replace(" ", "").replace("\n", "")

    response = get_result(code)
    ret = json.loads(response).get("result")

    submission = Submission.objects.get(id=submission_id)

    tags_to_add = []

    if ret == "None" or ret is None:
        tags_to_add.append(ProblemTag.objects.get(name="None"))
    else:
        flg = 1
        try:
            lis = ret.split(",")
        except:
            lis = [ret]
        for tag in lis:
            tag = tag.strip()
            try:
                tags_to_add.append(ProblemTag.objects.get(name=tag))
                print("添加标签：", tag)
            except ProblemTag.DoesNotExist:
                pass
            else:
                flg = 0

        if flg:
            tags_to_add.append(ProblemTag.objects.get(name="None"))

    # 添加所有标签到submission的recognized字段
    for tag in tags_to_add:
        submission.recognized.add(tag)

    # 保存submission
    submission.save()











